package org.springblade.common.utils;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * 工具栏
 */
public class FuncUtil {

    /**
     * 过来出符合条件对象
     *
     * @param dataList
     * @param predicate
     * @param <T>
     * @return
     */
    public static <T> List<T> filter(List<T> dataList, Predicate<T> predicate) {
        if (dataList == null || dataList.size() == 0) {
            return new ArrayList<>();
        }
        List<T> resList = new ArrayList<>();
        for (T t : dataList) {
            if (predicate.test(t)) {
                resList.add(t);
            }
        }
        return resList;
    }

    /**
     * 过来出所有的Id
     *
     * @param dataList
     * @param func
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> List<T> extract(List<E> dataList, Function<E, T> func) {
        if (dataList == null || dataList.size() == 0) {
            return new ArrayList<>();
        }
        List<T> resList = new ArrayList<>();
        T t;
        for (E e : dataList) {
            t = func.apply(e);
            if (t != null) {
                resList.add(t);
            }
        }
        return resList;
    }

    /**
     * 过来出所有的Id
     *
     * @param dataList
     * @param func
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> Set<T> extractToSet(List<E> dataList, Function<E, T> func) {
        if (dataList == null || dataList.size() == 0) {
            return new HashSet<>();
        }
        Set<T> resList = new HashSet<>();
        T t;
        for (E e : dataList) {
            t = func.apply(e);
            if (t != null) {
                resList.add(t);
            }
        }
        return resList;
    }


    /**
     * 转Map
     *
     * @param dataList
     * @param func
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> Map<T, E> map(List<E> dataList, Function<E, T> func) {
        if (dataList == null || dataList.size() == 0) {
            return new HashMap<>();
        }
        Map<T, E> resMap = new HashMap<>();
        T t;
        for (E e : dataList) {
            t = func.apply(e);
            if (t != null) {
                resMap.put(t, e);
            }
        }
        return resMap;
    }

    /**
     * 转MapList
     *
     * @param dataList
     * @param func
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T, E> Map<T, List<E>> mapList(List<E> dataList, Function<E, T> func) {
        if (dataList == null || dataList.size() == 0) {
            return new HashMap<>();
        }
        Map<T, List<E>> resMap = new HashMap<>();
        T t;
        List<E> itemList;
        for (E e : dataList) {
            t = func.apply(e);
            if (t != null) {
                itemList = resMap.get(t);
                if (itemList == null) {
                    itemList = new ArrayList<>();
                }
                itemList.add(e);
                resMap.put(t, itemList);
            }
        }
        return resMap;
    }

    /**
     * 连接到一块
     *
     * @param dataList
     * @param <E>
     * @return
     */
    public static <E> String join(Collection<E> dataList) {
        if (dataList == null || dataList.size() == 0) {
            return "";
        }
        StringBuilder res = new StringBuilder();
        boolean init = false;
        for (E e : dataList) {
            if (init) {
                res.append(",");
            } else {
                init = true;
            }
            if (e instanceof String) {
                res.append((String) e);
            } else {
                res.append(e);
            }
        }
        return res.toString();
    }

    /**
     * 转
     *
     * @param values
     * @return
     */
    public static List<Long> toLong(String values) {
        if (values == null || values.length() == 0) {
            return new ArrayList<>();
        }
        String [] vArr = values.split(",");
        List<Long> resList = new ArrayList<>();
        for (String e : vArr) {
            try {
                resList.add(Long.valueOf(e));
            } catch (Exception ex) {
            }
        }
        return resList;
    }

    /**
     * 转
     *
     * @param dbList
     * @return
     */
    public static List<Long> toLong(List<String> dbList) {
        if (dbList == null || dbList.size() == 0) {
            return new ArrayList<>();
        }
        List<Long> resList = new ArrayList<>();
        for (String e : dbList) {
            try {
                resList.add(Long.valueOf(e));
            } catch (Exception ex) {

            }

        }
        return resList;
    }


    /**
     * 判空，主要是为了简单记忆，这里做了个代理
     */
    public static boolean isEmpty(Object value) {
        if (value == null) {
            return true;
        }
        return ObjectUtil.isEmpty(value);
    }


    /**
     * 消息
     *
     * @param msg
     * @param params
     * @return
     */
    public static String msg(String msg, String... params) {
        if (params == null || params.length == 0) {
            return msg;
        }
        return StrUtil.format(msg, params);
    }


    /**
     * 获得某天最大时间 2020-02-19 23:59:59
     *
     * @param date
     * @return
     */
    public static Date dayEnd(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获得某天最小时间 2020-02-17 00:00:00
     *
     * @param date
     * @return
     */
    public static Date dayBegin(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 两个Map是否相等
     *
     * @param srcData
     * @param tarData
     * @return
     */
    public static boolean equals(Map<String, Object> srcData, Map<String, Object> tarData) {
        if (srcData == null || tarData == null) {
            return false;
        }
        if (srcData.size() != tarData.size()) {
            return false;
        }
        Object srcValue;
        Object tarValue;
        for (Map.Entry<String, Object> entry : tarData.entrySet()) {
            srcValue = entry.getValue();
            if (srcValue == null) {
                return false;
            }
            tarValue = entry.getValue();
            //不相等
            if (!srcValue.equals(tarValue)) {
                return false;
            }
        }
        return true;
    }
}